

#ifndef __NEW_SPRINTF_INCLUDE__
#define __NEW_SPRINTF_INCLUDE__

/**
typedef struct buff_header {
	unsigned int element_num;
	unsigned int len;
} __attribute__((packed)) buff_header_t;
*/

#define metamacro_argcount(...)  metamacro_at(20, __VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
#define metamacro_at(N, ...)  metamacro_concat(metamacro_at, N)(__VA_ARGS__)
#define metamacro_concat(A, B) metamacro_concat_(A, B)
#define metamacro_concat_(A, B) A ## B
#define metamacro_at20(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, ...) metamacro_head(__VA_ARGS__)
#define metamacro_head(...)  metamacro_head_(__VA_ARGS__, 0)
#define metamacro_head_(FIRST, ...) FIRST

#define PRIVATE_ARGS_GLUE(x, y) x y
#define PRIVATE_MACRO_CHOOSE_HELPER2(M,count)  M##count
#define PRIVATE_MACRO_CHOOSE_HELPER1(M,count)  PRIVATE_MACRO_CHOOSE_HELPER2(M,count)
#define PRIVATE_MACRO_CHOOSE_HELPER(M,count)   PRIVATE_MACRO_CHOOSE_HELPER1(M,count)
#define INVOKE_VAR_MACRO(M,...) PRIVATE_ARGS_GLUE(PRIVATE_MACRO_CHOOSE_HELPER(M,metamacro_argcount(__VA_ARGS__)), (__VA_ARGS__))

#define  ___ANONYMOUS1(type, var, line)  type  var##line 
#define  __ANONYMOUS0(type, line)  ___ANONYMOUS1(type, _anonymous, line) 
#define  ANONYMOUS(type)  __ANONYMOUS0(type, __LINE__) 

#define  __anonymous_name1(var, line)  var##line 
#define  ___anonymous_name0(line)  __anonymous_name1(_anonymous, line) 
#define  _anonymous_name ___anonymous_name0(__LINE__) 

#define buff_fotmat_temp(p_buf, len, p) \
	memcpy((unsigned char *)((p_buf) + len), (unsigned char *)&(p), sizeof(p)); \
	len += sizeof(p);
	
#define buffer_tlv_format2(p_buf, p1) \
({ \
	ANONYMOUS(int) = 0; \
	buff_header_t *p_header = (buff_header_t *)(p_buf); \
	p_header->element_num = 1; \
	_anonymous_name += sizeof(buff_header_t); \
	buff_fotmat_temp((p_buf), _anonymous_name, p1); \
	p_header->len  = _anonymous_name; \
}) 


#define buffer_tlv_format3(p_buf, p1, p2) \
({ \
	ANONYMOUS(int) = 0; \
	buff_header_t *p_header = (buff_header_t *)(p_buf); \
	p_header->element_num = 2; \
	_anonymous_name += sizeof(buff_header_t); \
	buff_fotmat_temp((p_buf), _anonymous_name, p1); \
	buff_fotmat_temp((p_buf), _anonymous_name, p2); \
	p_header->len  = _anonymous_name; \
}) 


#define buffer_tlv_format4(p_buf, p1, p2, p3) \
({ \
	ANONYMOUS(int) = 0; \
	buff_header_t *p_header = (buff_header_t *)(p_buf); \
	p_header->element_num = 3; \
	_anonymous_name += sizeof(buff_header_t); \
	buff_fotmat_temp((p_buf), _anonymous_name, (p1)); \
	buff_fotmat_temp((p_buf), _anonymous_name, (p2)); \
	buff_fotmat_temp((p_buf), _anonymous_name, (p3)); \
	p_header->len  = _anonymous_name; \
}) 


#define buffer_tlv_format5(p_buf, p1, p2, p3, p4) \
({ \
	ANONYMOUS(int) = 0; \
	buff_header_t *p_header = (buff_header_t *)(p_buf); \
	p_header->element_num = 4; \
	_anonymous_name += sizeof(buff_header_t); \
	buff_fotmat_temp((p_buf), _anonymous_name, p1); \
	buff_fotmat_temp((p_buf), _anonymous_name, p2); \
	buff_fotmat_temp((p_buf), _anonymous_name, p3); \
	buff_fotmat_temp((p_buf), _anonymous_name, p4); \
	p_header->len  = _anonymous_name; \
}) 


#define buffer_tlv_format6(p_buf, p1, p2, p3, p4, p5) \
({ \
	ANONYMOUS(int) = 0; \
	buff_header_t *p_header = (buff_header_t *)(p_buf); \
	p_header->element_num = 5; \
	_anonymous_name += sizeof(buff_header_t); \
	buff_fotmat_temp((p_buf), _anonymous_name, p1); \
	buff_fotmat_temp((p_buf), _anonymous_name, p2); \
	buff_fotmat_temp((p_buf), _anonymous_name, p3); \
	buff_fotmat_temp((p_buf), _anonymous_name, p4); \
	buff_fotmat_temp((p_buf), _anonymous_name, p5); \
	p_header->len  = _anonymous_name; \
}) 


#define buffer_tlv_format7(p_buf, p1, p2, p3, p4, p5, p6) \
({ \
	ANONYMOUS(int) = 0; \
	buff_header_t *p_header = (buff_header_t *)(p_buf); \
	p_header->element_num = 6; \
	_anonymous_name += sizeof(buff_header_t); \
	buff_fotmat_temp((p_buf), _anonymous_name, p1); \
	buff_fotmat_temp((p_buf), _anonymous_name, p2); \
	buff_fotmat_temp((p_buf), _anonymous_name, p3); \
	buff_fotmat_temp((p_buf), _anonymous_name, p4); \
	buff_fotmat_temp((p_buf), _anonymous_name, p5); \
	buff_fotmat_temp((p_buf), _anonymous_name, p6); \
	p_header->len  = _anonymous_name; \
}) 


#define buffer_tlv_format8(p_buf, p1, p2, p3, p4, p5, p6, p7) \
({ \
	ANONYMOUS(int) = 0; \
	buff_header_t *p_header = (buff_header_t *)(p_buf); \
	p_header->element_num = 7; \
	_anonymous_name += sizeof(buff_header_t); \
	buff_fotmat_temp((p_buf), _anonymous_name, p1); \
	buff_fotmat_temp((p_buf), _anonymous_name, p2); \
	buff_fotmat_temp((p_buf), _anonymous_name, p3); \
	buff_fotmat_temp((p_buf), _anonymous_name, p4); \
	buff_fotmat_temp((p_buf), _anonymous_name, p5); \
	buff_fotmat_temp((p_buf), _anonymous_name, p6); \
	buff_fotmat_temp((p_buf), _anonymous_name, p7); \
	p_header->len  = _anonymous_name; \
}) 


#define buffer_tlv_format9(p_buf, p1, p2, p3, p4, p5, p6, p7, p8) \
({ \
	ANONYMOUS(int) = 0; \
	buff_header_t *p_header = (buff_header_t *)(p_buf); \
	p_header->element_num = 8; \
	_anonymous_name += sizeof(buff_header_t); \
	buff_fotmat_temp((p_buf), _anonymous_name, p1); \
	buff_fotmat_temp((p_buf), _anonymous_name, p2); \
	buff_fotmat_temp((p_buf), _anonymous_name, p3); \
	buff_fotmat_temp((p_buf), _anonymous_name, p4); \
	buff_fotmat_temp((p_buf), _anonymous_name, p5); \
	buff_fotmat_temp((p_buf), _anonymous_name, p6); \
	buff_fotmat_temp((p_buf), _anonymous_name, p7); \
	buff_fotmat_temp((p_buf), _anonymous_name, p8); \
	p_header->len  = _anonymous_name; \
}) 


#define buffer_tlv_format10(p_buf, p1, p2, p3, p4, p5, p6, p7, p8, p9) \
({ \
	ANONYMOUS(int) = 0; \
	buff_header_t *p_header = (buff_header_t *)p_buf; \
	p_header->element_num = 9; \
	_anonymous_name += sizeof(buff_header_t); \
	buff_fotmat_temp((p_buf), _anonymous_name, p1); \
	buff_fotmat_temp((p_buf), _anonymous_name, p2); \
	buff_fotmat_temp((p_buf), _anonymous_name, p3); \
	buff_fotmat_temp((p_buf), _anonymous_name, p4); \
	buff_fotmat_temp((p_buf), _anonymous_name, p5); \
	buff_fotmat_temp((p_buf), _anonymous_name, p6); \
	buff_fotmat_temp((p_buf), _anonymous_name, p7); \
	buff_fotmat_temp((p_buf), _anonymous_name, p8); \
	buff_fotmat_temp((p_buf), _anonymous_name, p9); \
	p_header->len  = _anonymous_name; \
}) 


#define buffer_tlv_format11(p_buf, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10) \
({ \
	ANONYMOUS(int) = 0; \
	buff_header_t *p_header = (buff_header_t *)(p_buf); \
	p_header->element_num = 10; \
	_anonymous_name += sizeof(buff_header_t); \
	buff_fotmat_temp((p_buf), _anonymous_name, p1); \
	buff_fotmat_temp((p_buf), _anonymous_name, p2); \
	buff_fotmat_temp((p_buf), _anonymous_name, p3); \
	buff_fotmat_temp((p_buf), _anonymous_name, p4); \
	buff_fotmat_temp((p_buf), _anonymous_name, p5); \
	buff_fotmat_temp((p_buf), _anonymous_name, p6); \
	buff_fotmat_temp((p_buf), _anonymous_name, p7); \
	buff_fotmat_temp((p_buf), _anonymous_name, p8); \
	buff_fotmat_temp((p_buf), _anonymous_name, p9); \
	buff_fotmat_temp((p_buf), _anonymous_name, p10); \
	p_header->len  = _anonymous_name; \
}) 


#define buffer_tlv_format12(p_buf, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11) \
({ \
	ANONYMOUS(int) = 0; \
	buff_header_t *p_header = (buff_header_t *)(p_buf); \
	p_header->element_num = 11; \
	_anonymous_name += sizeof(buff_header_t); \
	buff_fotmat_temp((p_buf), _anonymous_name, p1); \
	buff_fotmat_temp((p_buf), _anonymous_name, p2); \
	buff_fotmat_temp((p_buf), _anonymous_name, p3); \
	buff_fotmat_temp((p_buf), _anonymous_name, p4); \
	buff_fotmat_temp((p_buf), _anonymous_name, p5); \
	buff_fotmat_temp((p_buf), _anonymous_name, p6); \
	buff_fotmat_temp((p_buf), _anonymous_name, p7); \
	buff_fotmat_temp((p_buf), _anonymous_name, p8); \
	buff_fotmat_temp((p_buf), _anonymous_name, p9); \
	buff_fotmat_temp((p_buf), _anonymous_name, p10); \
	buff_fotmat_temp((p_buf), _anonymous_name, p11); \
	p_header->len  = _anonymous_name; \
}) 


#define buffer_tlv_format13(p_buf, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12) \
({ \
	ANONYMOUS(int) = 0; \
	buff_header_t *p_header = (buff_header_t *)(p_buf); \
	p_header->element_num = 12; \
	_anonymous_name += sizeof(buff_header_t); \
	buff_fotmat_temp((p_buf), _anonymous_name, p1); \
	buff_fotmat_temp((p_buf), _anonymous_name, p2); \
	buff_fotmat_temp((p_buf), _anonymous_name, p3); \
	buff_fotmat_temp((p_buf), _anonymous_name, p4); \
	buff_fotmat_temp((p_buf), _anonymous_name, p5); \
	buff_fotmat_temp((p_buf), _anonymous_name, p6); \
	buff_fotmat_temp((p_buf), _anonymous_name, p7); \
	buff_fotmat_temp((p_buf), _anonymous_name, p8); \
	buff_fotmat_temp((p_buf), _anonymous_name, p9); \
	buff_fotmat_temp((p_buf), _anonymous_name, p10); \
	buff_fotmat_temp((p_buf), _anonymous_name, p11); \
	buff_fotmat_temp((p_buf), _anonymous_name, p12); \
	p_header->len  = _anonymous_name; \
}) 


#define buffer_tlv_format14(p_buf, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13) \
({ \
	ANONYMOUS(int) = 0; \
	buff_header_t *p_header = (buff_header_t *)(p_buf); \
	p_header->element_num = 13; \
	_anonymous_name += sizeof(buff_header_t); \
	buff_fotmat_temp((p_buf), _anonymous_name, p1); \
	buff_fotmat_temp((p_buf), _anonymous_name, p2); \
	buff_fotmat_temp((p_buf), _anonymous_name, p3); \
	buff_fotmat_temp((p_buf), _anonymous_name, p4); \
	buff_fotmat_temp((p_buf), _anonymous_name, p5); \
	buff_fotmat_temp((p_buf), _anonymous_name, p6); \
	buff_fotmat_temp((p_buf), _anonymous_name, p7); \
	buff_fotmat_temp((p_buf), _anonymous_name, p8); \
	buff_fotmat_temp((p_buf), _anonymous_name, p9); \
	buff_fotmat_temp((p_buf), _anonymous_name, p10); \
	buff_fotmat_temp((p_buf), _anonymous_name, p11); \
	buff_fotmat_temp((p_buf), _anonymous_name, p12); \
	buff_fotmat_temp((p_buf), _anonymous_name, p13); \
	p_header->len  = _anonymous_name; \
}) 


#define buffer_tlv_format15(p_buf, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14) \
({ \
	ANONYMOUS(int) = 0; \
	buff_header_t *p_header = (buff_header_t *)(p_buf); \
	p_header->element_num = 14; \
	_anonymous_name += sizeof(buff_header_t); \
	buff_fotmat_temp((p_buf), _anonymous_name, p1); \
	buff_fotmat_temp((p_buf), _anonymous_name, p2); \
	buff_fotmat_temp((p_buf), _anonymous_name, p3); \
	buff_fotmat_temp((p_buf), _anonymous_name, p4); \
	buff_fotmat_temp((p_buf), _anonymous_name, p5); \
	buff_fotmat_temp((p_buf), _anonymous_name, p6); \
	buff_fotmat_temp((p_buf), _anonymous_name, p7); \
	buff_fotmat_temp((p_buf), _anonymous_name, p8); \
	buff_fotmat_temp((p_buf), _anonymous_name, p9); \
	buff_fotmat_temp((p_buf), _anonymous_name, p10); \
	buff_fotmat_temp((p_buf), _anonymous_name, p11); \
	buff_fotmat_temp((p_buf), _anonymous_name, p12); \
	buff_fotmat_temp((p_buf), _anonymous_name, p13); \
	buff_fotmat_temp((p_buf), _anonymous_name, p14); \
	p_header->len  = _anonymous_name; \
}) 


#define buffer_tlv_format16(p_buf, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15) \
({ \
	ANONYMOUS(int) = 0; \
	buff_header_t *p_header = (buff_header_t *)(p_buf); \
	p_header->element_num = 15; \
	_anonymous_name += sizeof(buff_header_t); \
	buff_fotmat_temp((p_buf), _anonymous_name, p1); \
	buff_fotmat_temp((p_buf), _anonymous_name, p2); \
	buff_fotmat_temp((p_buf), _anonymous_name, p3); \
	buff_fotmat_temp((p_buf), _anonymous_name, p4); \
	buff_fotmat_temp((p_buf), _anonymous_name, p5); \
	buff_fotmat_temp((p_buf), _anonymous_name, p6); \
	buff_fotmat_temp((p_buf), _anonymous_name, p7); \
	buff_fotmat_temp((p_buf), _anonymous_name, p8); \
	buff_fotmat_temp((p_buf), _anonymous_name, p9); \
	buff_fotmat_temp((p_buf), _anonymous_name, p10); \
	buff_fotmat_temp((p_buf), _anonymous_name, p11); \
	buff_fotmat_temp((p_buf), _anonymous_name, p12); \
	buff_fotmat_temp((p_buf), _anonymous_name, p13); \
	buff_fotmat_temp((p_buf), _anonymous_name, p14); \
	buff_fotmat_temp((p_buf), _anonymous_name, p15); \
	p_header->len  = _anonymous_name; \
}) 


#define buffer_tlv_format17(p_buf, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16) \
({ \
	ANONYMOUS(int) = 0; \
	buff_header_t *p_header = (buff_header_t *)(p_buf); \
	p_header->element_num = 16; \
	_anonymous_name += sizeof(buff_header_t); \
	buff_fotmat_temp((p_buf), _anonymous_name, p1); \
	buff_fotmat_temp((p_buf), _anonymous_name, p2); \
	buff_fotmat_temp((p_buf), _anonymous_name, p3); \
	buff_fotmat_temp((p_buf), _anonymous_name, p4); \
	buff_fotmat_temp((p_buf), _anonymous_name, p5); \
	buff_fotmat_temp((p_buf), _anonymous_name, p6); \
	buff_fotmat_temp((p_buf), _anonymous_name, p7); \
	buff_fotmat_temp((p_buf), _anonymous_name, p8); \
	buff_fotmat_temp((p_buf), _anonymous_name, p9); \
	buff_fotmat_temp((p_buf), _anonymous_name, p10); \
	buff_fotmat_temp((p_buf), _anonymous_name, p11); \
	buff_fotmat_temp((p_buf), _anonymous_name, p12); \
	buff_fotmat_temp((p_buf), _anonymous_name, p13); \
	buff_fotmat_temp((p_buf), _anonymous_name, p14); \
	buff_fotmat_temp((p_buf), _anonymous_name, p15); \
	buff_fotmat_temp((p_buf), _anonymous_name, p16); \
	p_header->len  = _anonymous_name; \
}) 


#define buffer_tlv_format18(p_buf, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17) \
({ \
	ANONYMOUS(int) = 0; \
	buff_header_t *p_header = (buff_header_t *)(p_buf); \
	p_header->element_num = 17; \
	_anonymous_name += sizeof(buff_header_t); \
	buff_fotmat_temp((p_buf), _anonymous_name, p1); \
	buff_fotmat_temp((p_buf), _anonymous_name, p2); \
	buff_fotmat_temp((p_buf), _anonymous_name, p3); \
	buff_fotmat_temp((p_buf), _anonymous_name, p4); \
	buff_fotmat_temp((p_buf), _anonymous_name, p5); \
	buff_fotmat_temp((p_buf), _anonymous_name, p6); \
	buff_fotmat_temp((p_buf), _anonymous_name, p7); \
	buff_fotmat_temp((p_buf), _anonymous_name, p8); \
	buff_fotmat_temp((p_buf), _anonymous_name, p9); \
	buff_fotmat_temp((p_buf), _anonymous_name, p10); \
	buff_fotmat_temp((p_buf), _anonymous_name, p11); \
	buff_fotmat_temp((p_buf), _anonymous_name, p12); \
	buff_fotmat_temp((p_buf), _anonymous_name, p13); \
	buff_fotmat_temp((p_buf), _anonymous_name, p14); \
	buff_fotmat_temp((p_buf), _anonymous_name, p15); \
	buff_fotmat_temp((p_buf), _anonymous_name, p16); \
	buff_fotmat_temp((p_buf), _anonymous_name, p17); \
	p_header->len  = _anonymous_name; \
}) 


#define buffer_tlv_format19(p_buf, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18) \
({ \
	ANONYMOUS(int) = 0; \
	buff_header_t *p_header = (buff_header_t *)(p_buf); \
	p_header->element_num = 18; \
	_anonymous_name += sizeof(buff_header_t); \
	buff_fotmat_temp((p_buf), _anonymous_name, p1); \
	buff_fotmat_temp((p_buf), _anonymous_name, p2); \
	buff_fotmat_temp((p_buf), _anonymous_name, p3); \
	buff_fotmat_temp((p_buf), _anonymous_name, p4); \
	buff_fotmat_temp((p_buf), _anonymous_name, p5); \
	buff_fotmat_temp((p_buf), _anonymous_name, p6); \
	buff_fotmat_temp((p_buf), _anonymous_name, p7); \
	buff_fotmat_temp((p_buf), _anonymous_name, p8); \
	buff_fotmat_temp((p_buf), _anonymous_name, p9); \
	buff_fotmat_temp((p_buf), _anonymous_name, p10); \
	buff_fotmat_temp((p_buf), _anonymous_name, p11); \
	buff_fotmat_temp((p_buf), _anonymous_name, p12); \
	buff_fotmat_temp((p_buf), _anonymous_name, p13); \
	buff_fotmat_temp((p_buf), _anonymous_name, p14); \
	buff_fotmat_temp((p_buf), _anonymous_name, p15); \
	buff_fotmat_temp((p_buf), _anonymous_name, p16); \
	buff_fotmat_temp((p_buf), _anonymous_name, p17); \
	buff_fotmat_temp((p_buf), _anonymous_name, p18); \
	p_header->len  = _anonymous_name; \
}) 


#define buffer_tlv_format20(p_buf, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19) \
({ \
	ANONYMOUS(int) = 0; \
	buff_header_t *p_header = (buff_header_t *)(p_buf); \
	p_header->element_num = 19; \
	_anonymous_name += sizeof(buff_header_t); \
	buff_fotmat_temp((p_buf), _anonymous_name, p1); \
	buff_fotmat_temp((p_buf), _anonymous_name, p2); \
	buff_fotmat_temp((p_buf), _anonymous_name, p3); \
	buff_fotmat_temp((p_buf), _anonymous_name, p4); \
	buff_fotmat_temp((p_buf), _anonymous_name, p5); \
	buff_fotmat_temp((p_buf), _anonymous_name, p6); \
	buff_fotmat_temp((p_buf), _anonymous_name, p7); \
	buff_fotmat_temp((p_buf), _anonymous_name, p8); \
	buff_fotmat_temp((p_buf), _anonymous_name, p9); \
	buff_fotmat_temp((p_buf), _anonymous_name, p10); \
	buff_fotmat_temp((p_buf), _anonymous_name, p11); \
	buff_fotmat_temp((p_buf), _anonymous_name, p12); \
	buff_fotmat_temp((p_buf), _anonymous_name, p13); \
	buff_fotmat_temp((p_buf), _anonymous_name, p14); \
	buff_fotmat_temp((p_buf), _anonymous_name, p15); \
	buff_fotmat_temp((p_buf), _anonymous_name, p16); \
	buff_fotmat_temp((p_buf), _anonymous_name, p17); \
	buff_fotmat_temp((p_buf), _anonymous_name, p18); \
	buff_fotmat_temp((p_buf), _anonymous_name, p19); \
	p_header->len  = _anonymous_name; \
}) 


#define new_sprintf(...) INVOKE_VAR_MACRO(buffer_tlv_format, __VA_ARGS__);


#endif /* __NEW_SPRINTF_INCLUDE__ */
